package org.iati.mobile.dataexchange;

import java.io.IOException;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.json.JSONException;

import android.util.Log;


/**
 * @author Ionut Dobre
 * @date April 9, 2012
 */

/**
 * Provides utility methods for communicating with the server.
 */
final public class NetworkUtilities {
	/** 
	 * Timeout (in ms) we specify for each http request 
	 */
	private static final int HTTP_REQUEST_TIMEOUT_MS = 30 * 1000;

	/**
	 * The user agent
	 */
	private static final String USER_AGENT = "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2";

	/** 
	 * The tag used to log to adb console. 
	 */
	private static final String TAG = "NetworkUtilities";

	private NetworkUtilities() {

	}

	/**
	 * Configures the httpClient to connect to the URL provided.
	 */
	private static HttpClient getHttpClient() {
		HttpClient httpClient = new DefaultHttpClient();
		final HttpParams params = httpClient.getParams();

		httpClient.getParams().setParameter(CoreProtocolPNames.USER_AGENT, USER_AGENT);
		httpClient.getParams().setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET, HTTP.UTF_8); 
		HttpConnectionParams.setConnectionTimeout(params, HTTP_REQUEST_TIMEOUT_MS);
		HttpConnectionParams.setSoTimeout(params, HTTP_REQUEST_TIMEOUT_MS);
		ConnManagerParams.setTimeout(params, HTTP_REQUEST_TIMEOUT_MS);

		return httpClient;
	}

	/**
	 * @param URL
	 * 
	 * @return JSONObject
	 * @throws JSONException 
	 */
	public static String fetchFromServer(String URL)
			throws IOException {
		final HttpGet get = new HttpGet(URL);

		Log.d(TAG, "[NetworkUtilities] " + get.getURI().toString());

		final HttpResponse resp = getHttpClient().execute(get);
		final String response = EntityUtils.toString(resp.getEntity());

		if (resp.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
			// Our request to the server was successful
			return response;
		} else {
			Log.e(TAG, "Server error: " + resp.getStatusLine());
			throw new IOException();
		}
	}
	
	/**
	 * Executes the network requests on a separate thread.
	 * 
	 * @param runnable The runnable instance containing network operations to be executed.
	 */
	public static Thread performOnBackgroundThread(final Runnable runnable) {
		final Thread mThread = new Thread() {
			@Override
			public void run() {
				try {
					runnable.run();
				} finally {
					// ...
				}
			}
		};
		mThread.start();
		return mThread;
	}
}
